﻿#region License

// Copyright (c) 2008, BXO Solutions AB
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions are met:
// 
//     * Redistributions of source code must retain the above copyright notice, 
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright 
//       notice, this list of conditions and the following disclaimer in the 
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the BXO Solutions AB nor the names of its 
//       contributors may be used to endorse or promote products derived from 
//       this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#endregion

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Bxo.TestingPortal.Entities;
using Castle.MonoRail.ActiveRecordSupport;
using Castle.MonoRail.Framework;
using Castle.Services.Transaction;
using Rhino.Commons;

namespace Bxo.TestingPortal.WebApplication.Controllers {
    [Transactional]
    public class ScenarioController : BaseController {
        [Transaction]
        public virtual void Add([ARFetch("proj")] Project project) {
            if (project != null) {
                this.PropertyBag["project"] = project;
            } else {
                this.RenderView("Add_NoProject");
            }
        }

        [AccessibleThrough(Verb.Post)]
        [Transaction]
        public virtual void AddCommit([ARFetch("proj")] Project project, string summary, string instructions, string[] categories) {
            IEnumerable<Category> requestedCategories =
                    from category in project.Categories
                    join requestedIdAsString in categories
                            on category.Id.ToString(CultureInfo.InvariantCulture) equals requestedIdAsString
                    select category;

            var scenario = new Scenario(new ScenarioVersion(summary, instructions ?? String.Empty));
            project.Scenarios.Add(scenario);
            foreach (var category in requestedCategories) {
                scenario.Categories.Add(category);
            }

            this.PropertyBag["project"] = project;
            this.PropertyBag["scenario"] = scenario;
        }

        [Transaction]
        public virtual void Show([ARFetch("so")] Scenario scenario) {
            if (scenario != null) {
                this.PropertyBag["project"] = scenario.Project;
                this.PropertyBag["scenario"] = scenario;
            } else {
                this.RenderView("Show_NoScenario");
            }
        }

        [Transaction]
        public virtual void Edit([ARFetch("so")] Scenario scenario) {
            this.PropertyBag["summary"] = scenario.CurrentVersion.Summary;
            this.PropertyBag["instruction"] = scenario.CurrentVersion.Instruction;
            this.PropertyBag["categories"] = from c in scenario.Categories select c.Id.ToString(CultureInfo.InvariantCulture);

            this.PropertyBag["project"] = scenario.Project;
            this.PropertyBag["scenario"] = scenario;
        }

        [Transaction]
        [AccessibleThrough(Verb.Post)]
        public virtual void EditCommit([ARFetch("so")] Scenario scenario, string summary, string instruction, string[] categories) {
            if (! string.Equals(summary, scenario.CurrentVersion.Summary, StringComparison.InvariantCulture)
                || ! string.Equals(instruction, scenario.CurrentVersion.Instruction, StringComparison.InvariantCulture)) {
                scenario.Update(new ScenarioVersion(summary, instruction));
            }

            var proposedCategories = (from id in categories ?? new string[0] select Repository<Category>.Get(int.Parse(id))).ToList();

            var categoriesToAdd = proposedCategories.Except(scenario.Categories).ToList();
            var categoriesToRemove = scenario.Categories.Except(proposedCategories).ToList();

            categoriesToAdd.ForEach(category => scenario.Categories.Add(category));
            categoriesToRemove.ForEach(category => scenario.Categories.Remove(category));

            this.PropertyBag["project"] = scenario.Project;
            this.PropertyBag["scenario"] = scenario;
        }
    }
}